package com.hqd.share;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.Date;

public class Reflection {

    private String suffix;

    public static void main(String[] args) {
        Person p = new Person();
        Reflection r = new Reflection();
        r.setReflection(p);
        System.out.println(p.toString());
        r.getReflection(p);
    }

    private void setReflection(Person p) {
        Field[] fs = p.getClass().getDeclaredFields();
        suffix = "set";
        for (Field f : fs) {
            String mtdNm = suffix + getName(f.getName());
            String type = f.getGenericType().toString();
            try {
                switch (type) {
                    case "class java.lang.String":
                        p.getClass().getDeclaredMethod(mtdNm, String.class).invoke(p, "StringVal");
                        break;
                    case "int":
                        p.getClass().getDeclaredMethod(mtdNm, int.class).invoke(p, 10);
                        break;
                    case "class java.lang.Integer":
                        p.getClass().getDeclaredMethod(mtdNm, Integer.class).invoke(p, 20);
                        break;
                    case "boolean":
                        p.getClass().getDeclaredMethod(mtdNm, boolean.class).invoke(p, true);
                        break;
                    case "class java.lang.Boolean":
                        p.getClass().getDeclaredMethod(mtdNm, Boolean.class).invoke(p, false);
                        break;
                    case "short":
                        p.getClass().getDeclaredMethod(mtdNm, short.class).invoke(p, Short.MAX_VALUE);
                        break;
                    case "class java.lang.Short":
                        p.getClass().getDeclaredMethod(mtdNm, Short.class).invoke(p, Short.MAX_VALUE);
                        break;
                    case "long":
                        p.getClass().getDeclaredMethod(mtdNm, long.class).invoke(p, 50l);
                        break;
                    case "class java.lang.Long":
                        p.getClass().getDeclaredMethod(mtdNm, Long.class).invoke(p, 60l);
                        break;
                    case "float":
                        p.getClass().getDeclaredMethod(mtdNm, float.class).invoke(p, Float.MAX_VALUE);
                        break;
                    case "class java.lang.Float":
                        p.getClass().getDeclaredMethod(mtdNm, Float.class).invoke(p, Float.MAX_VALUE);
                        break;
                    case "double":
                        p.getClass().getDeclaredMethod(mtdNm, double.class).invoke(p, 3.654);
                        break;
                    case "class java.lang.Double":
                        p.getClass().getDeclaredMethod(mtdNm, Double.class).invoke(p, 4987.56464);
                        break;
                    case "char":
                        p.getClass().getDeclaredMethod(mtdNm, char.class).invoke(p, 'c');
                        break;
                    case "class java.lang.Character":
                        p.getClass().getDeclaredMethod(mtdNm, Character.class).invoke(p, 'd');
                        break;
                    case "class java.util.Date":
                        p.getClass().getDeclaredMethod(mtdNm, Date.class).invoke(p, new Date());
                        break;
                    case "class java.math.BigDecimal":
                        p.getClass().getDeclaredMethod(mtdNm, BigDecimal.class).invoke(p, BigDecimal.ONE);
                        break;
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    }

    private void getReflection(Person p) {
        Field[] fs = p.getClass().getDeclaredFields();
        for (Field f : fs) {
            suffix = "get";
            String type = f.getGenericType().toString();
            if ("boolean".equals(type)) {
                suffix = "is";
            }
            String mtdNm = suffix + getName(f.getName());
            try {
                System.out.println(f.getName() + ":" + p.getClass().getDeclaredMethod(mtdNm).invoke(p));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }

        }
    }

    private String getName(String fnm) {
        char[] cs = fnm.toCharArray();
        cs[0] -= 32;
        return new String(cs);
    }
}
